#ifndef DATACENTER_H
#define DATACENTER_H
#include <QWidget>
#include <QDateTime>
#include "data.h"
#include "../network/netclient.h"
namespace model
{

class DataCenter : public QObject
{
    Q_OBJECT
public:
    static DataCenter* getInstance();

    void ping(){netClient.ping();};

    //初始化websocket的信号和槽并建立连接
    void initWebSocket();
    void closeWebSocket();
    //初始化数据文件
    void initDataFile();
    //数据持久化（将数据存储到文件中）
    void saveDataFile();
    //将数据从文件加载到内容中
    void loadDataFile();

    //获取个人信息
    void getMyselfAsync();
    UserInfo* getMyself();
    void resetMyself(std::shared_ptr<zzy_mims::GetUserInfoRsp> resp);

    //获取会话列表

    void getSessionListAsync();
    void resetSessionList(std::shared_ptr<zzy_mims::GetChatSessionListRsp> resp);

    //获取好友列表

    void getFriendListAsync();
    void resetFriendList(std::shared_ptr<zzy_mims::GetFriendListRsp> resp);

    //获取好友申请列表

    void getApplyListAsync();
    void resetApplyList(std::shared_ptr<zzy_mims::GetPendingFriendEventListRsp>);

    //获取会话最近消息

    void getRecentMessageListAsync(const QString& sessionId,bool isUpdateUI);
    void resetRecentMessageList(std::shared_ptr<zzy_mims::GetRecentMsgRsp> rsp,const QString& sessionId);

    //将发送的文本消息数据发送给服务器
    void sendTextMessageAsync(const QString& sessionId,const QString& content);
    //发送图片消息
    void sendImageMessageAsync(const QString& sessionId,const QByteArray& content);
    //发送文件消息
    void sendFileMessageAsync(const QString& sessionId,const QByteArray& content,const QString& fileName);
    //发送语音消息
    void sendSpeechMessageAsync(const QString& sessionId,const QByteArray& content);

    //修改个人信息的名字
    void changeNicknameAsync(const QString& nickname);

    //修改个人信息的签名
    void changeDescAsync(const QString& desc);

    //获取验证码
    void getVertifyCodeAsync(const QString& phone);
    //修改手机号
    void changePhoneAsync(const QString& phone,const QString& verifyCodeId,const QString& verifyCode);
    //修改头像
    void changeAvatarAsync(const QByteArray& avatar);
    //删除好友
    void deleteFriendAsync(const QString& userId);
    //在内存中删除好友
    void removeFriend(const QString& userId);
    //向用户发送好友申请
    void sendApplyAsync(const QString& userId);
    //处理好友申请
    void processFriendApplyAsync(bool isAgree,const QString& applyUserId);
    //处理搜索用户请求
    void sreachUserAsync(const QString& key);
    void resetSearchResult(const QList<zzy_mims::UserInfo>& userList);
    //创建群聊会话
    void createSessionAsync(const QList<QString>& memberList);
    //加载群聊会话成员列表
    void getSessionMemberListAsync(const QString& sessionId);
    void resetSessionMemberList(const QString& sessionId,const QList<zzy_mims::UserInfo>& memberList);
    //根据关键字搜索历史消息
    void getSearchHistoryListAsync(const QString& key);
    void resetSearchHistoryList(const QList<zzy_mims::MessageInfo>& msgList);
    //根据时间搜索历史消息
    void getSearchHistoryListByTimeAsync(const QDateTime& beginTime,const QDateTime& endTime);
    //使用账号密码登录
    void userLoginAsync(const QString& name,const QString& pswd);
    //使用账号密码注册
    void userRegisterAsync(const QString& name,const QString& pswd);
    //使用手机号登录
    void phoneLoginAsync(const QString& phone,const QString& verifyCodeId,const QString& verifyCode);
    //使用手机号注册
    void phoneRegisterAsync(const QString& phone,const QString& verifyCodeId,const QString& verifyCode);
    //根据文件Id获取文件内容
    void getSingleFileAsync(const QString& fileId);
    //语音转文字
    void speechConvertTextAsync(const QString& fileId,const QByteArray& content);

    //删除好友申请
    model::UserInfo removeFromApplyList(const QString& userId);
    //增加好友
    void addFriend(const model::UserInfo& userInfo);
    //增加单聊会话
    void addSession(const QString& sessionId,const model::UserInfo& userInfo);
    //增加群聊会话
    void addSession(const zzy_mims::ChatSessionInfo &sessionInfo);
    QString getLoginSessionId(){return loginSessionId;};
    QList<SessionInfo>* getSessionList(){return sessionList;};
    QList<UserInfo>* getFriendList(){return friendList;};
    QList<UserInfo>* getApplyList(){return applyList;};
    QList<Message>* getRecentMessageList(const QString& sessionId)
    {
        if(recentMessages->count(sessionId))
            return &(*recentMessages)[sessionId];
        return nullptr;
    };
    QString getCurrentSessionId(){return currentSessionId;};
    int getUnread(const QString& sessionId){return (*unreadMessageCount)[sessionId];};
    QString getPhoneToChange(){return phoneToChange;};
    QString getCurrentVerifyCodeId(){return currentVerifyCodeId;};
    QList<UserInfo>* getSessionMemberList(const QString& sessionId)
    {
        if((*sessionMemberLists).count(sessionId)==0) return nullptr;
        return &(*sessionMemberLists)[sessionId];
    };
    QList<UserInfo>* getSearchUserList(){return searchUserResult;};
    QList<Message>* getSearchHistoryList(){return searchMessageResult;};
    void setPhoneToChange(const QString& phone){phoneToChange = phone;};
    void setCurrentVerifyCodeId(const QString& verifyCodeId){currentVerifyCodeId=verifyCodeId;};
    void setCurrentSessionId(const QString& sessionId){currentSessionId = sessionId;};
    void setNickname(const QString& nickname){if(myself) myself->nickname = nickname;};
    void setDesc(const QString& desc){
        if(myself)
            myself->description = desc;
    };
    void setPhone(const QString& phone){if(myself) myself->phone = phone;};
    void setAvatar(const QByteArray& avatar){if(myself) myself->avatar = makeIcon(avatar);}
    void setLoginSessionId(const QString& loginSessionId){this->loginSessionId=loginSessionId;};


    //辅助函数
    SessionInfo* findSessionInfoBySId(const QString& sessionId)
    {
        if(sessionList==nullptr) return nullptr;
        for(auto& info:*sessionList)
            if(info.chatSessionId==sessionId)
                return &info;
        return nullptr;
    }
    UserInfo* findFriendByUId(const QString& userId)
    {
        if(friendList==nullptr) return nullptr;
        for(auto& f:*friendList)
            if(f.userId==userId)
                return &f;
        return nullptr;
    }
    void addMessage(const Message& msg)
    {
        (*recentMessages)[msg.chatSessionId].push_back(msg);
    }
    void addUnread(const QString& sessionId)
    {
        ++(*unreadMessageCount)[sessionId];
        saveDataFile();
    };
    void clearUnread(const QString& sessionId)
    {
        (*unreadMessageCount)[sessionId]=0;
        saveDataFile();
    };

private:
    DataCenter();
    DataCenter(const DataCenter&);
    ~DataCenter();
    static DataCenter* instance;

    //下面是DataCenter要管理的所有的数据

    //当前客户端登录回话id
    QString loginSessionId = "";
    //客户端当前使用者信息
    UserInfo* myself =nullptr;


    //好友列表
    QList<UserInfo>* friendList = nullptr;
    //待处理的好友申请
    QList<UserInfo>* applyList = nullptr;
    //搜索到的好友结果
    QList<UserInfo>* searchUserResult = nullptr;

    //会话列表
    QList<SessionInfo>* sessionList = nullptr;
    //记录当前选中会话
    QString currentSessionId="";
    //记录每个会话的成员列表 <sid,list<user>>
    QHash<QString,QList<UserInfo>>* sessionMemberLists = nullptr;
    //会话的最近消息列表<sid,list<msg>>
    QHash<QString,QList<Message>>* recentMessages = nullptr;
    //会话的未读消息个数
    QHash<QString,int>* unreadMessageCount = nullptr;


    //搜索到的历史消息结果
    QList<Message>* searchMessageResult = nullptr;
    //短信验证码的验证ID
    QString currentVerifyCodeId = "";
    //要修改的手机号,防止用户提交时输出的手机号与发送验证码时不一致，因此保存在内存中
    QString phoneToChange;

    //网络通信客户端
    network::NetClient netClient;

signals:
    //自定义信号
    void getMyselfDone();
    void getSessionListDone();
    void getFriendListDone();
    void getApplyListDone();
    void getRecentMessageDone(const QString& sessionId);
    void getRecentMessageDoneNoUi(const QString& sessionId);
    void sendMessageDone(MessageType type,const QByteArray& content,const QString& extraInfo);
    void updateLastMessage(const QString& sessionId);
    void receiveMessageDone(const Message& msg);
    void changeNicknameDone();
    void changeDescDone();
    void getVerifyCodeDone();
    void changePhoneDone();
    void changeAvatarDone();
    void deleteFriend(const QString& uid);
    void deleteFriendDone();
    void clearCurrentSession();
    void acceptFriendApplyDone();
    void processFriendApplyDone();
    void searchUserDone();
    void createSessionDone();
    void getSessionMemberListDone(const QString& sessionId);
    void getSearchHistoryListDone();
    void userLoginDone();
    void userRegisterDone();
    void phoneLoginDone();
    void phoneRegisterDone();
    void getSingleFileDone(const QString& fileId,const QByteArray& content);
    void speechConvertTextDone(const QString& fileId,const QString& content);
};

};//model
#endif // DATACENTER_H
